package NetWork;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/**  基于UDP来编写一个简单的客服端和服务器的网络通信程序
  DatagramSocket 这个类,表示一个socket对象(在操作系统上,把这个socket对象当做一个文件来处理,相当于是文件描述符表的一项 )
  socket文件对应的 硬件设备是网卡 普通文件对应的 硬件设备是 硬盘 (一切皆文件)
  一个socket对象就能和另外一台主机通信了,要和多个主机通信,就要创建多个socket对象
  DatagramSocket无参构造 系统会自动分配出一个空闲的端口
  传入一个端口号,就是让当前的socket对象和这个指定的端口(整数)关联起来 进程中的socket对象和端口建立了联系
  DatagramPacket 这个类,表示 UDP中传输的一个报文
 *
 */


//一次通信中,涉及到的ip和端口有两组 1.源ip 和 源端口 2.目的ip 和目的端口 (由于当前客服端和服务器都在一个主机上,因此ip都是127.0.0.1(环回ip))
public class UdpEchoClient {
    private DatagramSocket socket;
    public String serverIp;
    public int serverPort;
    public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
        //这里不需要设定一个端口,让操作系统自己分配一个端口(随机挑一个空闲的,没有进程使用)
        //一个进程可以绑定多个端口(进程只要创建多个socket对象,就能关联不同的端口(socket和端口号是一对一的)),而一个端口不能被多个进程使用
        //为什么不建议手动设定一个端口原因是: 手动设定的端口号可能已经存在,而在设置一个同样的就会导致无法通信
        //服务器端口可以重复原因: 服务器上面运行的内容都是可控的,程序员可以安排那个程序取哪个端口
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
    public void start() throws IOException {
        System.out.println("客户端启动!!!");
        Scanner scanner = new Scanner(System.in);
        while (true) {
            //1.从控制台读取发送的数据
            System.out.print(">  ");
            String request = scanner.next();
            if(request.equals("exit")) return;
            //2.构造成UDP请求,并发送
            //构造这个requestPacket,需要把serverIp 和serverPort 都传入过来,但是此处的ip地址是一个字符串,需要把它转换为32位的整数
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(serverIp),serverPort);
            socket.send(requestPacket);
            //3.读取服务器的UDP响应,并解析
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(),0, responsePacket.getLength());
            //4.把解析好的结果显示出来
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
        client.start();
    }
}
